package com.example.student.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.student.entity.SysRole;
import com.example.student.entity.SysUser;
import com.example.student.entity.SysUserRole;
import com.example.student.exception.BusinessException;
import com.example.student.mapper.SysRoleMapper;
import com.example.student.mapper.SysUserMapper;
import com.example.student.mapper.SysUserRoleMapper;
import com.example.student.model.PageResult;
import com.example.student.model.PasswordUpdateDTO;
import com.example.student.model.UserVO;
import com.example.student.service.UserService;
import com.example.student.util.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private SysUserMapper userMapper;
    
    @Resource
    private SysRoleMapper roleMapper;
    
    @Resource
    private SysUserRoleMapper userRoleMapper;
    
    @Resource
    private PasswordEncoder passwordEncoder;
    
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final String DEFAULT_PASSWORD = "Admin123"; // 默认密码

    @Override
    public UserVO getCurrentUser() {
        // 获取当前登录用户ID
        Long userId = SecurityUtil.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 查询用户信息
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 查询用户角色
        List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId)
        );
        
        List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());
                
        List<String> roles = userRoles.stream().map(userRole -> {
            SysRole role = roleMapper.selectById(userRole.getRoleId());
            return role != null ? role.getRoleName() : null;
        }).filter(roleName -> roleName != null).collect(Collectors.toList());
        
        // 转换为VO
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setRoles(roles);
        userVO.setRoleIds(roleIds);
        
        // 格式化最后登录时间
        if (user.getLastLoginTime() != null) {
            userVO.setLastLoginTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(user.getLastLoginTime()));
        }
        
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfo(SysUser user) {
        // 获取当前登录用户ID
        Long userId = SecurityUtil.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 查询用户信息
        SysUser existUser = userMapper.selectById(userId);
        if (existUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 只允许更新部分字段
        SysUser updateUser = new SysUser();
        updateUser.setId(userId);
        updateUser.setRealName(user.getRealName());
        updateUser.setPhone(user.getPhone());
        updateUser.setEmail(user.getEmail());
        
        userMapper.updateById(updateUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changePassword(PasswordUpdateDTO passwordUpdateDTO) {
        // 获取当前登录用户ID
        Long userId = SecurityUtil.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 查询用户信息
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证旧密码
        if (!passwordEncoder.matches(passwordUpdateDTO.getOldPassword(), user.getPassword())) {
            throw new BusinessException("旧密码不正确");
        }
        
        // 更新密码
        SysUser updateUser = new SysUser();
        updateUser.setId(userId);
        updateUser.setPassword(passwordEncoder.encode(passwordUpdateDTO.getNewPassword()));
        
        userMapper.updateById(updateUser);
    }

    @Override
    public PageResult<UserVO> getUserList(String username, String realName, Integer status, Integer pageNum, Integer pageSize) {
        // 构建查询条件
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(username)) {
            queryWrapper.like(SysUser::getUsername, username);
        }
        
        if (StringUtils.hasText(realName)) {
            queryWrapper.like(SysUser::getRealName, realName);
        }
        
        if (status != null) {
            queryWrapper.eq(SysUser::getStatus, status);
        }
        
        // 分页查询
        Page<SysUser> page = new Page<>(pageNum, pageSize);
        Page<SysUser> userPage = userMapper.selectPage(page, queryWrapper);
        
        // 转换为VO
        List<UserVO> voList = new ArrayList<>();
        if (userPage.getRecords() != null && !userPage.getRecords().isEmpty()) {
            // 获取所有用户ID
            List<Long> userIds = userPage.getRecords().stream()
                    .map(SysUser::getId)
                    .collect(Collectors.toList());
            
            // 查询所有用户角色
            Map<Long, List<String>> userRoleMap = getUserRoles(userIds);
            
            // 转换为VO
            voList = userPage.getRecords().stream().map(user -> {
                UserVO vo = new UserVO();
                BeanUtils.copyProperties(user, vo);
                
                // 设置角色
                vo.setRoles(userRoleMap.getOrDefault(user.getId(), new ArrayList<>()));
                
                // 格式化最后登录时间
                if (user.getLastLoginTime() != null) {
                    vo.setLastLoginTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(user.getLastLoginTime()));
                }
                
                return vo;
            }).collect(Collectors.toList());
        }
        
        return new PageResult<>(voList, userPage.getTotal(), pageNum, pageSize);
    }

    @Override
    public UserVO getUserById(Long id) {
        // 查询用户信息
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 查询用户角色
        List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, id)
        );
        
        List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());
                
        List<String> roles = userRoles.stream().map(userRole -> {
            SysRole role = roleMapper.selectById(userRole.getRoleId());
            return role != null ? role.getRoleName() : null;
        }).filter(roleCode -> roleCode != null).collect(Collectors.toList());
        
        // 转换为VO
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setRoles(roles);
        userVO.setRoleIds(roleIds);
        
        // 格式化最后登录时间
        if (user.getLastLoginTime() != null) {
            userVO.setLastLoginTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(user.getLastLoginTime()));
        }
        
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUser(SysUser user) {
        // 检查用户名是否已存在
        SysUser existUser = userMapper.selectOne(
                new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, user.getUsername())
        );
        
        if (existUser != null) {
            throw new BusinessException("用户名已存在");
        }
        
        // 设置默认密码
        user.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
        user.setStatus(1); // 默认启用
        
        // 插入用户
        userMapper.insert(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(SysUser user) {
        // 检查用户是否存在
        SysUser existUser = userMapper.selectById(user.getId());
        if (existUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 如果修改了用户名，检查是否已存在
        if (!existUser.getUsername().equals(user.getUsername())) {
            SysUser sameNameUser = userMapper.selectOne(
                    new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, user.getUsername())
            );
            
            if (sameNameUser != null) {
                throw new BusinessException("用户名已存在");
            }
        }
        
        // 不允许修改密码
        user.setPassword(null);
        
        // 更新用户
        userMapper.updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long id) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 不允许删除管理员
        List<String> roles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, id)
        ).stream().map(userRole -> {
            SysRole role = roleMapper.selectById(userRole.getRoleId());
            return role != null ? role.getRoleCode() : null;
        }).filter(roleCode -> roleCode != null).collect(Collectors.toList());
        
        if (roles.contains("ROLE_ADMIN")) {
            throw new BusinessException("不允许删除管理员");
        }
        
        // 删除用户角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, id));
        
        // 删除用户
        userMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPassword(Long id) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 重置密码
        SysUser updateUser = new SysUser();
        updateUser.setId(id);
        updateUser.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
        
        userMapper.updateById(updateUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer status) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 不允许禁用管理员
        if (status != null && status == 0) {
            List<String> roles = userRoleMapper.selectList(
                    new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, id)
            ).stream().map(userRole -> {
                SysRole role = roleMapper.selectById(userRole.getRoleId());
                return role != null ? role.getRoleCode() : null;
            }).filter(roleCode -> roleCode != null).collect(Collectors.toList());
            
            if (roles.contains("ROLE_ADMIN")) {
                throw new BusinessException("不允许禁用管理员");
            }
        }
        
        // 更新状态
        SysUser updateUser = new SysUser();
        updateUser.setId(id);
        updateUser.setStatus(status);
        
        userMapper.updateById(updateUser);
    }
    
    /**
     * 获取用户角色
     */
    private Map<Long, List<String>> getUserRoles(List<Long> userIds) {
        // 查询用户角色关联
        List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds)
        );
        
        // 查询所有角色
        List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .distinct()
                .collect(Collectors.toList());
        
        // 如果没有找到角色，返回空映射
        if (roleIds.isEmpty()) {
            return Collections.emptyMap();
        }
        
        Map<Long, String> roleMap = roleMapper.selectList(
                new LambdaQueryWrapper<SysRole>().in(SysRole::getId, roleIds)
        ).stream().collect(Collectors.toMap(
                SysRole::getId,
                SysRole::getRoleName,
                (existing, replacement) -> existing
        ));
        
        // 组装用户角色
        return userRoles.stream()
                .collect(Collectors.groupingBy(
                        SysUserRole::getUserId,
                        Collectors.mapping(
                                userRole -> roleMap.get(userRole.getRoleId()),
                                Collectors.toList()
                        )
                ));
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignRoles(Long userId, List<Long> roleIds) {
        // 检查用户是否存在
        SysUser user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 删除用户现有角色
        userRoleMapper.delete(
            new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId)
        );
        
        // 分配新角色，每个用户只能分配一个角色
        if (roleIds != null && !roleIds.isEmpty()) {
            // 只取第一个角色ID
            Long roleId = roleIds.get(0);
            
            // 检查角色是否存在
            if (roleId == null || roleMapper.selectById(roleId) == null) {
                throw new BusinessException("角色不存在");
            }
            
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
        // 当roleIds为空或没有元素时，不执行任何插入操作，用户将没有任何角色
    }
} 